/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup Pasteboard
 * @{
 *
 * @brief 系统剪贴板支持复制和粘贴多种类型的数据。
 * 可以使用此模块接口操作纯文本、HTML、URI、像素图片等其他类型的数据。
 *
 * @since 13
 */

/**
 * @file oh_pasteboard.h
 *
 * @brief 提供访问系统剪贴板的接口、数据结构、枚举类型。
 *
 * @kit BasicServicesKit
 * @include <database/pasteboard/oh_pasteboard.h>
 * @library libpasteboard.so
 * @syscap SystemCapability.MiscServices.Pasteboard
 *
 * @since 13
 */

#ifndef OH_PASTEBOARD_H
#define OH_PASTEBOARD_H

#include <inttypes.h>
#include <stdbool.h>
#include "database/udmf/udmf.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 剪贴板的数据变更类型。
 *
 * @since 13
 */
typedef enum Pasteboard_NotifyType {
    /**
     * @brief 本地设备剪贴板数据变更。
     */
    NOTIFY_LOCAL_DATA_CHANGE = 1,
    /**
     * @brief 组网内的非本地设备剪贴板数据变更。
     */
    NOTIFY_REMOTE_DATA_CHANGE = 2
} Pasteboard_NotifyType;

/**
 * @brief 定义文件拷贝冲突时的选项。
 *
 * @since 15
 */
typedef enum Pasteboard_FileConflictOptions {
    /**
     * @brief 目标路径存在同文件名时覆盖。
     */
    PASTEBOARD_OVERWRITE = 0,
    /**
     * @brief 目标路径存在同文件名时跳过。
     */
    PASTEBOARD_SKIP = 1
} Pasteboard_FileConflictOptions;

/**
 * @brief 定义进度条指示选项。
 *
 * @since 15
 */
typedef enum Pasteboard_ProgressIndicator {
    /**
     * @brief 不采用系统默认进度显示。
     */
    PASTEBOARD_NONE = 0,
    /**
     * @brief 采用系统默认进度显示。
     */
    PASTEBOARD_DEFAULT = 1
} Pasteboard_ProgressIndicator;

/**
 * @brief 定义进度上报的数据结构。
 *
 * @since 15
 */
typedef struct Pasteboard_ProgressInfo Pasteboard_ProgressInfo;

/**
 * @brief 定义获取粘贴数据时返回上报进度信息的回调函数。
 *
 * @param progressInfo 通知给应用的进度信息。
 * @since 15
 */
typedef void (*OH_Pasteboard_ProgressListener)(Pasteboard_ProgressInfo* progressInfo);

/**
 * @brief 表示从剪贴板获取粘贴数据和进度时需要写入的参数。
 *
 * @since 15
 */
typedef struct Pasteboard_GetDataParams Pasteboard_GetDataParams;

/**
 * @brief 定义剪贴板内容变更时触发的回调函数。
 *
 * @param context 上下文信息，由函数{@link OH_PasteboardObserver_SetData}传入。
 * @param type 数据变更的类型。详见：{@link Pasteboard_NotifyType}。
 * @since 13
 */
typedef void (*Pasteboard_Notify)(void* context, Pasteboard_NotifyType type);

/**
 * @brief 定义用于释放上下文的回调函数，剪贴板数据变更观察者对象销毁时触发。
 * @param context 要释放的上下文指针。
 * @since 13
 */
typedef void (*Pasteboard_Finalize)(void* context);

/**
 * @brief 定义剪贴板数据变更观察者。
 *
 * @since 13
 */
typedef struct OH_PasteboardObserver OH_PasteboardObserver;

/**
 * @brief 创建一个剪贴板数据变更观察者{@link OH_PasteboardObserver}指针及实例对象。
 *
 * @return 执行成功时返回一个指向剪贴板数据变更观察者{@link OH_PasteboardObserver}实例对象的指针，否则返回空指针。
 * 当不再需要使用指针时，请使用{@link OH_PasteboardObserver_Destroy}销毁实例对象，否则会导致内存泄漏。
 * @see OH_PasteboardObserver。
 * @since 13
 */
OH_PasteboardObserver* OH_PasteboardObserver_Create();

/**
 * @brief 销毁剪贴板数据变更观察者{@link OH_PasteboardObserver}指针指向的实例对象。
 *
 * @param observer 表示指向剪贴板数据变更观察者{@link OH_PasteboardObserver}实例的指针。
 * @return 返回执行的错误码。错误码定义详见{@link PASTEBOARD_ErrCode}。
 *         若返回{@link ERR_OK}，表示指向成功。
 *         若返回{@link ERR_INVALID_PARAMETER}，表示传入了无效参数。
 * @see OH_PasteboardObserver PASTEBOARD_ErrCode。
 * @since 13
 */
int OH_PasteboardObserver_Destroy(OH_PasteboardObserver* observer);

/**
 * @brief 向剪贴板数据变更观察者设置回调函数。
 *
 * @param observer 表示指向剪贴板数据变更观察者{@link OH_PasteboardObserver}实例的指针。
 * @param context 表示指向上下文数据的指针，将作为第一个参数传入{@link Pasteboard_Notify}。
 * @param callback 表示数据变更回调函数。详见：{@link Pasteboard_Notify}。
 * @param finalize 表示可选的回调函数，可以用于剪贴板数据变更观察者销毁时释放上下文数据。详见：{@link Pasteboard_Finalize}。
 * @return 返回执行的错误码。错误码定义详见{@link PASTEBOARD_ErrCode}。
 *         若返回{@link ERR_OK}，表示指向成功。
 *         若返回{@link ERR_INVALID_PARAMETER}，表示传入了无效参数。
 * @see OH_PasteboardObserver Pasteboard_Notify PASTEBOARD_ErrCode。
 * @since 13
 */
int OH_PasteboardObserver_SetData(OH_PasteboardObserver* observer, void* context,
    const Pasteboard_Notify callback, const Pasteboard_Finalize finalize);

/**
 * @brief 定义剪贴板对象，用以操作系统剪贴板。
 *
 * @since 13
 */
typedef struct OH_Pasteboard OH_Pasteboard;

/**
 * @brief 创建剪贴板{@link OH_Pasteboard}指针及实例对象。
 *
 * @return 执行成功则返回一个指向剪贴板{@link OH_Pasteboard}实例对象的指针，否则返回nulllptr。
 * @see OH_Pasteboard。
 * @since 13
 */
OH_Pasteboard* OH_Pasteboard_Create();

/**
 * @brief 销毁剪贴板{@link OH_Pasteboard}实例对象。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @see OH_Pasteboard。
 * @since 13
 */
void OH_Pasteboard_Destroy(OH_Pasteboard* pasteboard);

/**
 * @brief 订阅剪贴板的数据变更事件。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @param type 表示订阅的剪贴板数据变更类型，详见：{@link Pasteboard_NotifyType}。
 * @param observer 表示指向剪贴板数据变更观察者{@link OH_PasteboardObserver}实例的指针。
 *                 它指定了剪贴板数据变更时触发的回调函数，详见：{@link OH_PasteboardObserver}。
 * @return 返回执行的错误码。错误码定义详见{@link PASTEBOARD_ErrCode}。
 *         若返回{@link ERR_OK}，表示指向成功。
 *         若返回{@link ERR_INVALID_PARAMETER}，表示传入了无效参数。
 * @see OH_Pasteboard OH_PasteboardObserver Pasteboard_NotifyType PASTEBOARD_ErrCode。
 * @since 13
 */
int OH_Pasteboard_Subscribe(OH_Pasteboard* pasteboard, int type, const OH_PasteboardObserver* observer);

/**
 * @brief 取消对剪贴板数据变更事件的订阅。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @param type 表示订阅的剪贴板数据变更类型，详见：{@link Pasteboard_NotifyType}。
 * @param observer 表示指向剪贴板数据变更观察者{@link OH_PasteboardObserver}实例的指针。
 *                 它指定了剪贴板数据变更时触发的回调函数，详见：{@link OH_PasteboardObserver}。
 * @return 返回执行的错误码。错误码定义详见{@link PASTEBOARD_ErrCode}。
 *         若返回{@link ERR_OK}，表示指向成功。
 *         若返回{@link ERR_INVALID_PARAMETER}，表示传入了无效参数。
 * @see OH_Pasteboard OH_PasteboardObserver Pasteboard_NotifyType PASTEBOARD_ErrCode。
 * @since 13
 */
int OH_Pasteboard_Unsubscribe(OH_Pasteboard* pasteboard, int type, const OH_PasteboardObserver* observer);

/**
 * @brief 判断剪贴板中的数据是否来自远端设备。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @return 返回剪贴板中的数据是否来自远端设备。返回true表示剪贴板中的数据来自远端设备，返回false表示剪贴板中数据来自本端设备。
 * @see OH_Pasteboard。
 * @since 13
 */
bool OH_Pasteboard_IsRemoteData(OH_Pasteboard* pasteboard);

/**
 * @brief 获取剪贴板中数据的数据源。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @param source 表示用于存放剪贴板数据数据源实例的指针，开发者需在调用接口前申请指针指向的内存。
 * @param len 表示source指针对应的内存长度，当内存长度不足时调用接口会失败，建议长度：128。
 * @return 返回执行的错误码。错误码定义详见{@link PASTEBOARD_ErrCode}。
 *         若返回{@link ERR_OK}，表示指向成功。
 *         若返回{@link ERR_INVALID_PARAMETER}，表示传入了无效参数。
 * @see OH_Pasteboard PASTEBOARD_ErrCode。
 * @since 13
 */
int OH_Pasteboard_GetDataSource(OH_Pasteboard* pasteboard, char* source, unsigned int len);

/**
 * @brief 判断剪贴板中是否有指定类型的数据。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @param type 表示要检查的数据类型。包含剪贴板基础数据类型与自定义数据类型，其中剪贴板基础数据类型有："text/plain"、"text/html"、"text/uri"、"text/want"和"pixelMap"。
 * @return 返回剪贴板中是否有指定类型的数据。返回true表示剪贴板中包含指定类型的数据，返回false表示剪贴板中没有指定类型的数据。
 * @see OH_Pasteboard。
 * @since 13
 */
bool OH_Pasteboard_HasType(OH_Pasteboard* pasteboard, const char* type);

/**
 * @brief 判断剪贴板中是否有数据。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @return 返回剪贴板中是否有数据。返回true表示剪贴板中有数据，返回false表示剪贴板中没有数据。
 * @see OH_Pasteboard。
 * @since 13
 */
bool OH_Pasteboard_HasData(OH_Pasteboard* pasteboard);

/**
 * @brief 获取剪贴板中的数据。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @param status 该参数是输出参数，表示执行的错误码。错误码定义详见{@link PASTEBOARD_ErrCode}。
 * @return 执行成功时返回统一数据对象{@link OH_UdmfData}实例的指针。否则返回空指针。
 * @see OH_Pasteboard OH_UdmfData PASTEBOARD_ErrCode。
 * @since 13
 */
OH_UdmfData* OH_Pasteboard_GetData(OH_Pasteboard* pasteboard, int* status);

/**
 * @brief 将统一数据对象数据写入剪贴板。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @param data 表示指向统一数据对象{@link OH_UdmfData}实例的指针。
 * @return 返回执行的错误码。错误码定义详见{@link PASTEBOARD_ErrCode}。
 *         若返回{@link ERR_OK}，表示指向成功。
 *         若返回{@link ERR_INVALID_PARAMETER}，表示传入了无效参数。
 * @see OH_Pasteboard OH_UdmfData PASTEBOARD_ErrCode。
 * @since 13
 */
int OH_Pasteboard_SetData(OH_Pasteboard* pasteboard, OH_UdmfData* data);

/**
 * @brief 清空剪贴板中的数据。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @return 返回执行的错误码。错误码定义详见{@link PASTEBOARD_ErrCode}。
 *         若返回{@link ERR_OK}，表示指向成功。
 *         若返回{@link ERR_INVALID_PARAMETER}，表示传入了无效参数。
 * @see OH_Pasteboard PASTEBOARD_ErrCode。
 * @since 13
 */
int OH_Pasteboard_ClearData(OH_Pasteboard* pasteboard);

/**
 * @brief 获取剪贴板中的MIME类型。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @param count 该参数是输出参数，结果集中的类型数量会写入该变量。
 * @return 执行成功时返回剪贴板所有内容的MIME类型，否则返回nullptr。
 * @see OH_Pasteboard。
 * @since 14
 */
char **OH_Pasteboard_GetMimeTypes(OH_Pasteboard *pasteboard, unsigned int *count);

/**
 * @brief 创建剪贴板{@link Pasteboard_GetDataParams}指针及实例对象。
 *
 * @return 执行成功时返回一个指向剪贴板{@link Pasteboard_GetDataParams}实例对象的指针，否则返回空指针。 当不再需要使用指针时，
 * 请使用{@link OH_Pasteboard_GetDataParams_Destroy}销毁实例对象，否则会导致内存泄漏。
 * @see Pasteboard_GetDataParams
 * @since 15
 */
Pasteboard_GetDataParams *OH_Pasteboard_GetDataParams_Create(void);

/**
 * @brief 销毁剪贴板{@link Pasteboard_GetDataParams}指针指向的实例对象。
 *
 * @param params 表示指向剪贴板{@link OH_Pasteboard_GetDataParams}的指针。
 * @see Pasteboard_GetDataParams
 * @since 15
 */
void OH_Pasteboard_GetDataParams_Destroy(Pasteboard_GetDataParams* params);

/**
 * @brief 向剪贴板{@link Pasteboard_GetDataParams}设置进度条指示选项，可选择是否采用系统默认进度显示。
 *
 * @param params 表示指向剪贴板{@link OH_Pasteboard_GetDataParams}的指针。
 * @param progressIndicator 定义进度条指示选项。
 * @see Pasteboard_GetDataParams Pasteboard_ProgressIndicator
 * @since 15
 */
void OH_Pasteboard_GetDataParams_SetProgressIndicator(Pasteboard_GetDataParams* params,
    Pasteboard_ProgressIndicator progressIndicator);

/**
 * @brief 设置拷贝文件时目标路径。若不支持文件处理，则不需要设置此参数；若应用涉及复杂文件处理策略或需要区分文件多路径存储，
 * 建议不设置此参数，由应用自行完成文件copy处理。
 *
 * @param params 表示指向剪贴板{@link OH_Pasteboard_GetDataParams}的指针。
 * @param destUri 定义拷贝文件目标路径。
 * @param destUriLen 定义拷贝文件目标路径长度。
 * @see Pasteboard_GetDataParams
 * @since 15
 */
void OH_Pasteboard_GetDataParams_SetDestUri(Pasteboard_GetDataParams* params, const char* destUri, uint32_t destUriLen);

/**
 * @brief 向剪贴板{@link Pasteboard_GetDataParams}设置文件冲突选项。
 *
 * @param params 表示指向剪贴板{@link OH_Pasteboard_GetDataParams}的指针。
 * @param option 定义文件拷贝冲突时的选项，默认为PASTEBOARD_OVERWRITE。
 * @see Pasteboard_GetDataParams Pasteboard_FileConflictOptions
 * @since 15
 */
void OH_Pasteboard_GetDataParams_SetFileConflictOptions(Pasteboard_GetDataParams* params,
    Pasteboard_FileConflictOptions option);

/**
 * @brief 向剪贴板{@link Pasteboard_GetDataParams}设置进度上报回调函数。
 *
 * @param params 表示指向剪贴板{@link OH_Pasteboard_GetDataParams}的指针。
 * @param listener 表示进度上报回调函数。
 * @see Pasteboard_GetDataParams OH_Pasteboard_ProgressListener
 * @since 15
 */
void OH_Pasteboard_GetDataParams_SetProgressListener(Pasteboard_GetDataParams* params,
    const OH_Pasteboard_ProgressListener listener);

/**
 * @brief 从{@link Pasteboard_ProgressInfo}获取粘贴进度。
 *
 * @param progressInfo 表示指向剪贴板{@link Pasteboard_ProgressInfo}的指针。
 * @return 返回粘贴进度百分比。
 * @see Pasteboard_ProgressInfo
 * @since 15
 */
int OH_Pasteboard_ProgressInfo_GetProgress(Pasteboard_ProgressInfo* progressInfo);

/**
 * @brief 定义取消函数，用于在获取粘贴数据时取消正在进行的粘贴动作。
 *
 * @param params 表示指向剪贴板{@link OH_Pasteboard_GetDataParams}的指针。
 * @see Pasteboard_GetDataParams。
 * @since 15
 */
void OH_Pasteboard_ProgressCancel(Pasteboard_GetDataParams* params);

/**
 * @brief 获取剪贴板的数据以及粘贴进度，不支持对文件夹的拷贝。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @param params 表示指向剪贴板{@link OH_Pasteboard_GetDataParams}的指针。
 * @param status 该参数是输出参数，表示执行的错误码。错误码定义详见{@link PASTEBOARD_ErrCode}。
 * @return 执行成功时返回统一数据对象{@link OH_PasteData}实例的指针。否则返回空指针。
 * @see OH_Pasteboard OH_PasteData PASTEBOARD_ErrCode。
 * @since 15
 */
OH_UdmfData* OH_Pasteboard_GetDataWithProgress(OH_Pasteboard* pasteboard, Pasteboard_GetDataParams* params,
    int* status);

/**
 * @brief 获取剪贴板内容的变化次数。
 *
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @return 执行成功时返回剪贴板内容的变化次数，否则返回0。
 * 当剪贴板内容过期或调用OH_Pasteboard_ClearData等接口导致剪贴板内容为空时，内容变化次数不会因此改变。
 * 系统重启或剪贴板服务异常重启时，剪贴板内容变化次数重新从0开始计数。对同一内容连续多次复制会被视作多次更改，每次复制均会导致内容变化次数增加。
 * @since 18
 */
uint32_t OH_Pasteboard_GetChangeCount(OH_Pasteboard *pasteboard);

/**
 * @brief 通知剪贴板从应用同步所有延迟数据，与延迟复制接口{@link OH_UdmfRecordProvider_SetData}搭配使用。
 * 当应用使用延迟复制功能复制时，仅将应用支持的数据类型写入剪贴板。
 * 应用应在退出时，重新调用{@link OH_Pasteboard_SetData}接口主动提交所有复制数据或调用{@link OH_Pasteboard_SyncDelayedDataAsync}接口通知剪贴板获取全量数据，
 * 等待数据同步完成再继续退出，否则可能导致其他应用粘贴获取不到数据。
 * @note 调用此接口会延长退出过程，建议应用直接设置数据到剪贴板，而不是调用延迟复制接口和同步延迟数据接口。
 * @param pasteboard 表示指向剪贴板{@link OH_Pasteboard}实例的指针。
 * @param callback 数据同步完成后调用的回调函数指针，errorCode表示同步任务的结果，错误码定义详见{@link PASTEBOARD_ErrCode}。
 * @since 21
 */
void OH_Pasteboard_SyncDelayedDataAsync(OH_Pasteboard* pasteboard, void (*callback)(int errorCode));
#ifdef __cplusplus
};
#endif

/** @} */
#endif